$.fn.treeTable = function (opts) {
    opts = $.extend({
        theme: 'default',
        expandLevel: 1,
        column: 0,
        onSelect: function($treeTable, id){},
        beforeExpand: function($treeTable, id){}
    }, opts);

    var $treeTable = this;
    $treeTable.addClass('tree_table');

    var css = {
        'N' : opts.theme + '_node',
        'AN' : opts.theme + '_active_node',
        'O' : opts.theme + '_open',
        'LO' : opts.theme + '_last_open',
        'S' : opts.theme + '_shut',
        'LS' : opts.theme + '_last_shut',
        'HO' : opts.theme + '_hover_open',
        'HS' : opts.theme + '_hover_shut',
        'HLO' : opts.theme + '_hover_last_open',
        'HLS' : opts.theme + '_hover_last_shut',
        'L' : opts.theme + '_leaf',
        'LL' : opts.theme + '_last_leaf',
        'B' : opts.theme + '_blank',
        'V' : opts.theme + '_vertline'
    };

    var pMap = {}, cMap = {};
    var $trs = $treeTable.find('tr');
    initRelation($trs, true);

    $treeTable.click(function (event) {
        var $target = $(event.target);

        if ($target.attr('controller')) {
            $target = $target.parents('tr[haschild]').find('[arrow]');
            //判断是否是叶子节点
            if ($target.attr('class').indexOf(css['AN']) == -1 && $target.attr('class').indexOf(css['N']) == -1) { return; }
            var id = $target.parents('tr[haschild]')[0].id;
            if (opts.onSelect && opts.onSelect($treeTable, id) === false) { return; }
        }

        if ($target.attr('arrow')) {
            var className = $target.attr('class');
            if (className == css['AN'] + ' ' + css['HLO'] || className == css['AN'] + ' ' + css['HO']) {
                var id = $target.parents('tr[haschild]')[0].id;
                $target.attr('class', css['AN'] + " " + (className.indexOf(css['HO']) != -1 ?  css['HS'] : css['HLS']));

                //关闭所有孩子的tr
                shut(id);

            } else if (className == css['AN'] + ' ' + css['HLS'] || className == css['AN'] + ' ' + css['HS']) {
                var id = $target.parents('tr')[0].id;
                $target.attr('class', css['AN'] + " " + (className.indexOf(css['HS']) != -1 ? css['HO'] : css['HLO']));

                opts.beforeExpand($treeTable, id);
                //展开所有直属节点，根据图标展开子孙节点
                open(id);

            }
        }
    });

    $treeTable.mouseover(hoverActiveNode).mouseout(hoverActiveNode);

    function hoverActiveNode(event) {
        var $target = $(event.target);

        if ($target.attr('controller')) {
            $target = $target.parents('tr[haschild]').find('[arrow]');
        }

        if ($target.attr('arrow')) {
            var className = $target.attr('class');
            if (className && !className.indexOf(css['AN'])) {
                var len = opts.theme.length + 1;
                className = className.split(' ')[1].substr(len);
                if (className.indexOf('hover_') === 0) {
                    className = opts.theme + '_' + className.substr(6);
                } else {
                    className = opts.theme + '_hover_' + className;
                }

                $target.attr('class', css['AN'] + ' ' + className);

            }
        }
    }

    /** 初始化节点关系　*/
    function initRelation($trs, hideLevel) {
        //构造父子关系
        $trs.each(function (i) {
            var pId = $(this).attr('pId') || 0;
            pMap[pId] || (pMap[pId] = []);
            pMap[pId].push(this.id);
            cMap[this.id] = pId;

            //给这个tr增加类为了提高选择器的效率
            $(this).addClass(pId);
        }).find('[controller]').css('cursor', 'pointer');

        //标识父节点是否有孩子、是否最后一个节点
        $trs.each(function (i) {
            if (!this.id) { return; }
            var $tr = $(this);

            pMap[this.id] && $tr.attr('hasChild', true);
            var pArr = pMap[cMap[this.id]];
            if (pArr[0] == this.id) {
                $tr.attr('isFirstOne', true);
            } else {
                var prevId = 0;
                for (var i = 0; i < pArr.length; i++) {
                    if (pArr[i] == this.id) { break; }
                    prevId = pArr[i];
                }
                $tr.attr('prevId', prevId);
            }

            pArr[pArr.length - 1] == this.id && $tr.attr('isLastOne', true);

            var depth = getDepth(this.id);
            $tr.attr('depth', depth);

            //格式化节点
            formatNode(this);

            //判断是否要隐藏限制的层次
            if (hideLevel) {
                depth > opts.expandLevel && $tr.hide();
                //判断是否小于深度，如果小于深度则要换成展开的图标
                if ($tr.attr('hasChild') && $tr.attr('depth') < opts.expandLevel) {
                    var className = $tr.attr('isLastOne') ? css['LO'] : css['O'];
                    $tr.find('.' + css['AN']).attr('class', css['AN'] + ' ' + className);
                }
            }
        });

        //递归获取深度
        function getDepth(id) {
            if (id == undefined || cMap[id] == 0) {
                return 1;
            }
            var $parentDepth = getDepth(cMap[id]);
            return $parentDepth + 1;
        }
    }

    //递归关闭所有的孩子
    function shut(id) {
        if (!pMap[id]) { return false; }
        for (var i = 0; i < pMap[id].length; i++) {
            shut(pMap[id][i]);
        }
        $('tr.' + id, $treeTable).hide();
    }

    //根据历史记录来展开节点
    function open(id) {
        $('tr.' + id, $treeTable).show();
        if (!pMap[id]) { return false; }
        for (var i = 0; i < pMap[id].length; i++) {
            var cId = pMap[id][i];
            if (pMap[cId]) {
                var className = $('#' + cId, $treeTable).find('.' + css['AN']).attr('class');
                //如果子节点是展开图表的，则需要展开此节点
                (className == css['AN'] + ' ' + css['O'] || className == css['AN'] + ' ' + css['LO']) && open(cId);
            }
        }
    }

    function formatNode(tr) {
        var $cur = $(tr);
        var id = tr.id;

        //-------------下面一大段都是获取$preSpan---------
        if (cMap[id] == 0) {
            //如果是顶级节点，则没有prev_span
            var $preSpan = $('<span class="prev_span"></span>');
        } else {
            //先判断是否有上一个兄弟节点
            if (!$cur.attr('isFirstOne')) {
                var $preSpan = $('#' + $cur.attr('prevId'), $treeTable).children("td").eq(opts.column).find('.prev_span').clone();
            } else {
                var $parent = $('#' + cMap[id], $treeTable);
                //没有上一个兄弟节点，则使用父节点的prev_span
                var $preSpan = $parent.children("td").eq(opts.column).find('.prev_span').clone();

                //如果父亲后面没有兄弟，则直接加空白，若有则加竖线
                if ($parent.attr('isLastOne')) {
                    $preSpan.append('<span class="' + css['N'] + ' ' + css['B'] + '"></span>');
                } else {
                    $preSpan.append('<span class="' + css['N'] + ' ' + css['V'] + '"></span>');
                }
            }
        }
        //------------------------------------------------

        if ($cur.attr('hasChild')) {
            //如果有下一个节点，并且下一个节点的父亲与当前节点的父亲相同，则说明该节点不是最后一个节点
            var className = $cur.attr('isLastOne') ? css['LS'] : css['S'];
            className = css['AN'] + ' ' + className;
        } else {
            var className = css['N'] + ' ' + ($cur.attr('isLastOne') ? css['LL'] : css['L']);
        }

        var $td = $cur.children("td").eq(opts.column);
        $td.prepend('<span arrow="true" class="' + className + '"></span>').prepend($preSpan);
    }
    $treeTable.addChilds = function(trsHtml) {
        var $trs = $(trsHtml);
        if (!$trs.length) { return false; }

        var pId = $($trs[0]).attr('pId');
        if (!pId) { return false; }

        //插入到最后一个孩子后面，或者直接插在父节点后面
        var insertId = pMap[pId] && pMap[pId][pMap[pId].length - 1] || pId;
        $('#' + insertId, $treeTable).after($trs);
        initRelation($trs);
    };

    return $treeTable;
};